In [38]:
# 초기화
import cv2
from matplotlib import pyplot as plt
import numpy as np
def plt_show(title, path):
plt.axis('off')
plt.imshow(path)
plt.title(title)
plt.show()
In [39]:
if __name__ == '__main__':
img = cv2.imread('./images/Lenna.jpg', cv2.IMREAD_GRAYSCALE)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt_show('Image', img)
cv2.imwrite('Lena_1.bmp', img)
cv2.imwrite('Lena_2.jpg', img)
영상 불러오기 imread 함수¶
- 래스터 그래픽 영상 파일 형식들을 메모리로 읽어들임
- 파일 시그니처(file signature)를 읽어 적절한 코덱을 결정하고, 압축 해제된 영상 데이터 구조에 필요한 메모리 할당과 같은 복잡한 작업들을 처리
- 확장자가 아닌 파일 시그니처를 읽어 파일의 포맷을 분석
- 함수명 :
cv2.imread(fileName, flags) - 매개변수
fileName (str): 읽어들일 영상 파일의 경로(상대 경로 또는 절대 경로 이용)flags (int): 영상 파일을 읽을 때 옵션cv2.IMREAD_COLOR: 컬러로 읽어 들이기 (3채널 BGR 영상) (1)cv2.IMREAD_GRAYSCALE: 회색조로 읽어 들이기 (0)cv2.IMREAD_UNCHANGED: alpha channel까지 포함하여 읽기 (-1)cv2.IMREAD_UNCHANGED: alpha channel까지 포함하여 읽기 (-1)cv2.IMREAD_REDUCED_GRAYSCALE_2: 1채널 ½크기 grayscale 영상cv2.IMREAD_REDUCED_GRAYSCALE_4: 1채널 1/4크기 grayscale 영상cv2.IMREAD_REDUCED_GRAYSCALE_8: 1채널 1/8크기 grayscale 영상cv2.IMREAD_REDUCED_COLOR_2: 3채널 1/2크기 BGR영상cv2.IMREAD_REDUCED_COLOR_4: 3채널 1/4크기 BGR영상cv2.IMREAD_REDUCED_COLOR_8: 3채널 1/8크기 BGR영상
- 리턴값 : image 객체 행렬 (numpy.ndarray)
In [40]:
if __name__ == '__main__':
# cv2.IMREAD_COLOR: 컬러로 읽어 들이기 (3채널 BGR 영상) (1)
IMREAD_COLOR = cv2.imread('./images/Lenna.jpg', cv2.IMREAD_COLOR)
IMREAD_COLOR = cv2.cvtColor(IMREAD_COLOR, cv2.COLOR_BGR2RGB)
plt_show('IMREAD_COLOR', IMREAD_COLOR)
# cv2.IMREAD_GRAYSCALE: 회색조로 읽어 들이기 (0)
IMREAD_GRAYSCALE = cv2.imread('./images/Lenna.jpg', cv2.IMREAD_GRAYSCALE)
IMREAD_GRAYSCALE = cv2.cvtColor(IMREAD_GRAYSCALE, cv2.COLOR_BGR2RGB)
plt_show('IMREAD_GRAYSCALE', IMREAD_GRAYSCALE)
# cv2.IMREAD_UNCHANGED: alpha channel까지 포함하여 읽기 (-1)
IMREAD_UNCHANGED = cv2.imread('./images/Lenna.jpg', cv2.IMREAD_UNCHANGED)
IMREAD_UNCHANGED = cv2.cvtColor(IMREAD_UNCHANGED, cv2.COLOR_BGR2RGB)
plt_show('IMREAD_UNCHANGED', IMREAD_UNCHANGED)
# cv2.IMREAD_REDUCED_GRAYSCALE_2: 1채널 ½크기 grayscale 영상
IMREAD_REDUCED_GRAYSCALE_2 = cv2.imread('./images/Lenna.jpg', cv2.IMREAD_REDUCED_GRAYSCALE_2)
IMREAD_REDUCED_GRAYSCALE_2 = cv2.cvtColor(IMREAD_REDUCED_GRAYSCALE_2, cv2.COLOR_BGR2RGB)
plt_show('IMREAD_REDUCED_GRAYSCALE_2', IMREAD_REDUCED_GRAYSCALE_2)
# cv2.IMREAD_REDUCED_GRAYSCALE_4: 1채널 1/4크기 grayscale 영상
IMREAD_REDUCED_GRAYSCALE_4 = cv2.imread('./images/Lenna.jpg', cv2.IMREAD_REDUCED_GRAYSCALE_4)
IMREAD_REDUCED_GRAYSCALE_4 = cv2.cvtColor(IMREAD_REDUCED_GRAYSCALE_4, cv2.COLOR_BGR2RGB)
plt_show('IMREAD_REDUCED_GRAYSCALE_4', IMREAD_REDUCED_GRAYSCALE_4)
# cv2.IMREAD_REDUCED_GRAYSCALE_8: 1채널 1/8크기 grayscale 영상
IMREAD_REDUCED_GRAYSCALE_8 = cv2.imread('./images/Lenna.jpg', cv2.IMREAD_REDUCED_GRAYSCALE_8)
IMREAD_REDUCED_GRAYSCALE_8 = cv2.cvtColor(IMREAD_REDUCED_GRAYSCALE_8, cv2.COLOR_BGR2RGB)
plt_show('IMREAD_REDUCED_GRAYSCALE_8', IMREAD_REDUCED_GRAYSCALE_8)
# cv2.IMREAD_REDUCED_COLOR_2: 3채널 1/2크기 BGR영상
IMREAD_REDUCED_COLOR_2 = cv2.imread('./images/Lenna.jpg', cv2.IMREAD_REDUCED_COLOR_2)
IMREAD_REDUCED_COLOR_2 = cv2.cvtColor(IMREAD_REDUCED_COLOR_2, cv2.COLOR_BGR2RGB)
plt_show('IMREAD_REDUCED_COLOR_2', IMREAD_REDUCED_COLOR_2)
# cv2.IMREAD_REDUCED_COLOR_4: 3채널 1/4크기 BGR영상
IMREAD_REDUCED_COLOR_4 = cv2.imread('./images/Lenna.jpg', cv2.IMREAD_REDUCED_COLOR_4)
IMREAD_REDUCED_COLOR_4 = cv2.cvtColor(IMREAD_REDUCED_COLOR_4, cv2.COLOR_BGR2RGB)
plt_show('IMREAD_REDUCED_COLOR_4', IMREAD_REDUCED_COLOR_4)
# cv2.IMREAD_REDUCED_COLOR_8: 3채널 1/8크기 BGR영상
IMREAD_REDUCED_COLOR_8 = cv2.imread('./images/Lenna.jpg', cv2.IMREAD_REDUCED_COLOR_8)
IMREAD_REDUCED_COLOR_8 = cv2.cvtColor(IMREAD_REDUCED_COLOR_8, cv2.COLOR_BGR2RGB)
plt_show('IMREAD_REDUCED_COLOR_8', IMREAD_REDUCED_COLOR_8)
영상 저장 imwrite 함수¶
- 영상을 레스터 그래픽 영상 파일 형식으로 저장함
- 저장하는 파일의 형식은 파일 확장자에 따라서 결정됨
- .jpg / .bmp / .png
- 함수명 :
cv2.imwrite(fileName, image, flags) - 매개변수
fileName (str): 저장할 영상 파일의 경로(상대 경로 또는 절대 경로 이용)image (numpy.ndarray): 저장할 영상 데이터flags (int): 영상 파일을 저장할 때 옵션
- 리턴값 :
True 또는 False (bool)
In [41]:
if __name__ == '__main__':
img = cv2.imread('./images/cameraman.jpg', cv2.IMREAD_UNCHANGED)
cv2.imwrite('./output/cameraman.jpg', img)
cv2.imwrite('./output/cameraman.bmp', img)
cv2.imwrite('./output/cameraman.png', img)
jpg_img = cv2.imread('./output/cameraman.jpg', cv2.IMREAD_UNCHANGED)
plt_show('jpg_img', jpg_img)
bmp_img = cv2.imread('./output/cameraman.bmp', cv2.IMREAD_UNCHANGED)
plt_show('bmp_img', bmp_img)
png_img = cv2.imread('./output/cameraman.png', cv2.IMREAD_UNCHANGED)
plt_show('png_img', png_img)
libpng warning: iCCP: profile 'icc': 0h: PCS illuminant is not D50
영상 화면 출력 imshow 함수¶
영상을 지정한 윈도우에 출력
"윈도우 이름"에 따라서 출력되는 윈도우가 결정
일치하는 윈도우 이름이 없으면 새로운 윈도우를 생성하여 출력
- 함수명 :
cv2.imshow(window_name, image) - 매개변수
window_name (str): 윈도우 창의 Title 내용image (numpy.ndarray): 출력할 영상 데이터
- 리턴값 : N/A
In [42]:
if __name__ == '__main__':
img = cv2.imread('./images/Lenna.jpg', cv2.IMREAD_GRAYSCALE)
cv2.imshow("image", img)
cv2.waitKey(0)
영상정보 출력¶
- 입력 영상에 대한 넓이, 높이 채널 수 정보 출력
In [43]:
if __name__ == '__main__':
# color image
img = cv2.imread('./images/Lenna.jpg', cv2.IMREAD_UNCHANGED)
h, w, c = img.shape
print(f'height : {h}, width : {w}, channel : {c}')
#grayscale image
img = cv2.imread('./images/Lenna.jpg', cv2.IMREAD_GRAYSCALE)
h, w = img.shape
print(f'height : {h}, width : {w}')
height : 512, width : 512, channel : 3 height : 512, width : 512
waitkey 함수¶
- 지정된 시간 동안 사용자가 키를 입력할 때까지 프로그램을 대기
- 대기하는 시간은 밀리 초(milliseconds) 단위로서 1,000이 1초에 해당
- 함수명 : `cv2.waitKey(delay)
- 매개변수
delay (int): 대기할 시간 (밀리 초 단위) delay가 0보다 작거나 같은 경우 무한 (infinite) 대기를 위미
- 리턴값 : 사용자가 입력한 키 값 (int)
In [44]:
img = cv2.imread('./images/Lenna.jpg', cv2.IMREAD_UNCHANGED)
cv2.imshow('Image', img)
# cv2.waitKey(1000)
key = cv2.waitKey(0)
print(f'key = {key} ({chr(key)})')
key = 27 ()
이진화 코드 : threshold() 함수¶
- threshold 함수는 입력한 영상 데이터에 대해 임계값 필터링을 수행하여 이진영상을 생성
- 함수 : `cv2.threshold(src, thresh, maxval, type)
- 매개변수
src (numpy.ndarray): 입력 영상 데이터thresh: 임계값 (threshold value)maxval: THRESH_BINARY & THRESH_BINARY_INV에서 사용할 최대값type: 임계값 필터링 종류 (Trheshold Type)
- 리턴값 : 출력 영상데이터 (numpy.ndarray)
In [45]:
if __name__ == '__main__':
src = cv2.imread('./images/Lenna.jpg', cv2.IMREAD_GRAYSCALE)
src = cv2.cvtColor(src, cv2.COLOR_BGR2RGB)
plt_show('origin_img', src)
_, THRESH_BINARY = cv2.threshold(src, 160, 255, cv2.THRESH_BINARY)
plt_show('THRESH_BINARY', THRESH_BINARY)
_, THRESH_BINARY_INV = cv2.threshold(src, 160, 255, cv2.THRESH_BINARY_INV)
plt_show('THRESH_BINARY_INV', THRESH_BINARY_INV)
_, THRESH_TRUNC = cv2.threshold(src, 160, 255, cv2.THRESH_TRUNC)
plt_show('THRESH_TRUNC', THRESH_TRUNC)
_, THRESH_TOZERO = cv2.threshold(src, 160, 255, cv2.THRESH_TOZERO)
plt_show('THRESH_TOZERO', THRESH_TOZERO)
_, THRESH_TOZERO_INV = cv2.threshold(src, 160, 255, cv2.THRESH_TOZERO_INV)
plt_show('THRESH_TOZERO_INV', THRESH_TOZERO_INV)
Week 4¶
기하학적 변환¶
기본 변환 - Scaling¶
크기변환 - 확대 및 축소¶
- 영상의 크기를 변경하는 처리
- OpenCV에서는 cv2.resize() 함수를 사용하여 크기를 변환
- 픽셀값 보간 과정에서는 최소 이웃 보간법(nearest neighbor interpolation), 양방향 선형 보간법(bilinear interpolation), Cubic 보간법(cubic interpolation) 방법들을 많이 사용
영상 크기 변환 함수 : resize() 함수¶
- 입력된 영상 데이터에 대하여 크기를 변환
- 함수명 :
cv2.resize(src, dsize, fx, fy, interpolation) - 매개변수
src (numpy.ndarray): 변환시킬 영상 데이터dsize: 가로, 세로, 형태의 튜플 ex) (100, 200)fx: 가로 크기의 배수, 2배로 크게 하려면 2, 반으로 줄이려면 0.5fy: 세로 크기의 배수, 2배로 크게 하려면 2, 반으로 줄이려면 0.5interpolation: 보간법 방식cv2.INTER_NEAREST: 최소 근접 보간cv2.INTER_LINEAR: 양방향 선형 보간cv2.INTER_CUIBIC: 양방향 선형 보간cv2.INTER_AREA: 픽셀 리샘플링 보간cv2.INTER_LANCZOS4: Lanczos 보간cv2.INTER_LINEAR_EXACT: Bit exact bilinear interpolationcv2.INTER_NEAREST_EXACT: Bit exact nearest neighbor interpolation
- 리턴값 : 출력 영상 데이터 (numpy.ndarray)
In [52]:
# Scailing
if __name__ == '__main__':
ori_img = cv2.imread('../images/Lenna.jpg', cv2.IMREAD_UNCHANGED)
ori_img = cv2.cvtColor(ori_img, cv2.COLOR_BGR2RGB)
rs_img = cv2.resize(ori_img, (64, 64), interpolation=cv2.INTER_LINEAR)
plt_show('128x64 image', rs_img)
z_img1 = cv2.resize(rs_img, (512, 512), interpolation=cv2.INTER_NEAREST)
z_img2 = cv2.resize(rs_img, None, fx=8, fy=8, interpolation=cv2.INTER_NEAREST)
z_img3 = cv2.resize(rs_img, None, fx=8, fy=8, interpolation=cv2.INTER_CUBIC)
z_img4 = cv2.resize(rs_img, None, fx=8, fy=8, interpolation=cv2.INTER_AREA)
z_img5 = cv2.resize(rs_img, None, fx=8, fy=8, interpolation=cv2.INTER_LANCZOS4)
z_img6 = cv2.resize(rs_img, None, fx=8, fy=8, interpolation=cv2.INTER_LINEAR_EXACT)
z_img7 = cv2.resize(rs_img, None, fx=8, fy=8, interpolation=cv2.INTER_NEAREST_EXACT)
plt_show('Nearest neighbor intp image', z_img1)
plt_show('Bilinear intp image', z_img2)
plt_show('Cubic intp image', z_img3)
plt_show('Area intp image', z_img4)
plt_show('lanczos intp image', z_img5)
plt_show('linear_exact intp image', z_img6)
plt_show('nearest_exact intp image', z_img7)
- 함수명 :
cv2.warpAffine(src, M, dsize, dst, flags, borderMode, borderValue) - 매개변수
src (numpy.ndarray): 변환시킬 영상 데이터M: (2x3) 변환 행렬dsize: 가로, 세로, 형태의 튜플 ex) (100, 200)dst: 출력 영상 데이터 (dszie 크기로 조정됨)flags: 보간 방법과 역변환 방법 설정borderMode: 픽셀 외삽(extracpolation) 방법 BorderTypescv2.BORDER_CONSTANT: iiiiii|abcdefgh|iiiiii 여기서 i는 지정한 borderValuecv2.BORDER_REPLICATE: aaaaaa|abcdefgh|hhhhhh 경계 복사cv2.BORDER_REFLECT: fedcba|abcdefgh|hgfedcb 경계부터 반사cv2.BORDER_WRAP: cdefgh|abcdefgh|abcdefg 소실된 영역을 이동 변환
borderValue: BORDER_CONSTANT 경우 사용할 상수값 (기본값은 0)
- 리턴값 : 출력 영상 데이터 (numpy.ndarray)
In [47]:
if __name__ == '__main__':
ori_img = cv2.imread("../images/Lenna.jpg", cv2.IMREAD_UNCHANGED)
ori_img = cv2.cvtColor(ori_img, cv2.COLOR_BGR2RGB)
plt_show('Original image', ori_img)
rows, cols = ori_img.shape[:2] # channel 여부 무시
Mat = np.float32([[1, 0, 30],[0, 1, 60]])
t_image1 = cv2.warpAffine(ori_img, Mat, (cols, rows))
# 이동된 여백 지정된 색으로
t_image2 = cv2.warpAffine(ori_img, Mat, (cols, rows),
borderMode=cv2.BORDER_CONSTANT,
borderValue=(255,255,255))
# 이동된 여백 경계면 늘이기
t_image3 = cv2.warpAffine(ori_img, Mat, (cols, rows),
borderMode=cv2.BORDER_REPLICATE)
# 이동된 여백 반전으로 채우기
t_image4 = cv2.warpAffine(ori_img, Mat, (cols, rows),
borderMode=cv2.BORDER_REFLECT)
# 이동된 여백 자투리 사진으로 채우기
t_image5 = cv2.warpAffine(ori_img, Mat, (cols, rows),
borderMode=cv2.BORDER_WRAP)
plt_show('Translation image - default', t_image1)
plt_show('Translation image - BORDER_CONSTANT', t_image2)
plt_show('Translation image - BORDER_REPLICATE', t_image3)
plt_show('Translation image - BORDER_REFLECT', t_image4)
plt_show('Translation image - BORDER_WRAP', t_image5)
In [48]:
if __name__ == '__main__':
ori_img = cv2.imread("../images/Lenna.jpg", cv2.IMREAD_UNCHANGED)
ori_img = cv2.cvtColor(ori_img, cv2.COLOR_BGR2RGB)
plt_show('Original image', ori_img)
rows, cols = ori_img.shape[:2] # channel 여부 무시
# getRotationMatrix2D((센터 좌표 type: tuple), (회전각도 type: float), (확대률 typel: float))
Mat1 = cv2.getRotationMatrix2D((0, 0), 45, 1.0)
Mat2 = cv2.getRotationMatrix2D((cols / 2, rows / 2), 45, 1.0)
Mat3 = cv2.getRotationMatrix2D((cols / 2, rows / 2), 90, 1.0)
r_image1 = cv2.warpAffine(ori_img, Mat1, (cols, rows))
r_image2 = cv2.warpAffine(ori_img, Mat2, (cols, rows),
borderMode=cv2.BORDER_REPLICATE)
r_image3 = cv2.warpAffine(ori_img, Mat2, (cols, rows),
borderMode=cv2.BORDER_DEFAULT)
r_image4 = cv2.warpAffine(ori_img, Mat3, (cols, rows))
plt_show('Rotation image - (0, 0), 45)', r_image1)
plt_show('Rotation image - (w/2, h/2), 45 - replicate)', r_image2)
plt_show('Rotation image - (w/2, h/2), 45 - default)', r_image3)
plt_show('Rotation image - (w/2, h/2), 90', r_image4)
- 함수명 :
cv2.flip(src, flipCode) - 매개변수
src(numpy.ndarray): 변환시킬 입력영상 데이터flipCode: 플립 방법을 지정하는 코드- x축 대칭 = 0
- y축 대칭 = 양수
- x축 및 y축 대칭 = 음수
- 리턴값 : 출력 영상 데이터 (numpy.ndarray)
In [49]:
if __name__ == '__main__':
ori_img = cv2.imread("../images/Lenna.jpg", cv2.IMREAD_UNCHANGED)
ori_img = cv2.cvtColor(ori_img, cv2.COLOR_BGR2RGB)
f_image0 = cv2.flip(ori_img, 0)
f_imagep1 = cv2.flip(ori_img, 1)
f_imagem1 = cv2.flip(ori_img, -1)
plt_show('ori img', ori_img)
plt_show('flip img (up/down, 0)', f_image0)
plt_show('flip img (left/right, 1)', f_image0)
plt_show('flip img (y=x, -1)', f_image0)
In [50]:
import numpy as np
import cv2
ori_img = cv2.imread('./images/Lenna.jpg', cv2.IMREAD_UNCHANGED)
c_img = cv2.cvtColor(ori_img, cv2.COLOR_BGR2RGB)
plt_show('Origin Image', c_img)
rows, cols = ori_img.shape[:2] # channel 여부 무시
# pts1 좌표 표시
pts1 = np.float32([[200, 200], [300, 200], [200, 300]])
cv2.circle(c_img, (200, 200), 9, (255, 0, 0), -1)
cv2.circle(c_img, (300, 200), 9, (0, 255, 0), -1)
cv2.circle(c_img, (200, 300), 9, (0, 0, 255), -1)
pts2 = np.float32([[200, 200], [350, 200], [200, 250]])
Mat1 = cv2.getAffineTransform(pts1, pts2)
r_image1 = cv2.warpAffine(c_img, Mat1, (cols, rows))
pts2 = np.float32([[200, 200], [300, 230], [260, 300]])
Mat2 = cv2.getAffineTransform(pts1, pts2)
r_image2 = cv2.warpAffine(c_img, Mat2, (cols, rows))
pts2 = np.float32([[200, 200], [100, 170], [170, 100]])
Mat3 = cv2.getAffineTransform(pts1, pts2)
r_image3 = cv2.warpAffine(c_img, Mat3, (cols, rows))
plt_show('Affine 1 image', r_image1)
plt_show('Affine 2 image', r_image2)
plt_show('Affine 3 image', r_image3)
In [51]:
if __name__ == '__main__':
ori_img = cv2.imread("./images/Lenna.jpg", cv2.IMREAD_COLOR)
ori_img = cv2.cvtColor(ori_img, cv2.COLOR_BGR2RGB)
rows, cols = ori_img.shape[:2] # channel 여부 무시
# pts1 좌표 표시
pts1 = np.float32([[80, 280], [400, 220], [250, 480], [60, 420]])
cv2.circle(ori_img, (80, 280), 9, (255, 0, 0), -1)
cv2.circle(ori_img, (400, 220), 9, (0, 255, 0), -1)
cv2.circle(ori_img, (250, 480), 9, (0, 0, 255), -1)
cv2.circle(ori_img, (60, 420), 9, (0, 255, 255), -1)
cv2.line(ori_img, (0, 340), (511, 340), (255, 0, 0), 2)
cv2.line(ori_img, (0, 380), (511, 380), (0, 0, 255), 2)
pts2 = np.float32([[10, 10], [502, 10], [502, 502], [10, 502]])
Mat1 = cv2.getPerspectiveTransform(pts1, pts2)
print('Perspective matrix')
print(Mat1)
r_image = cv2.warpPerspective(ori_img, Mat1, (cols, rows))
plt_show('Original image', ori_img)
plt_show('Perspective image', r_image)
Perspective matrix [[ 3.23187758e+00 4.47028347e-01 -3.74074102e+02] [ 5.45182861e-01 2.73071886e+00 -7.98571868e+02] [ 3.12600637e-03 -1.02027266e-03 1.00000000e+00]]